/***********************************************************************************/
/* Code license:  GNU General Public License v3                                    */
/* Main page:     https://code.google.com/p/library-cross-platform/                */
/* Issue tracker: https://code.google.com/p/library-cross-platform/issues/list     */
/***********************************************************************************/

#include "parserstate.h"
#include <iostream>


using namespace std;

START_STATE_MAP_BASE_CLASS(parserstate)
  STATE(START_STATE,      parserstate::stateStart)
  STATE(STATE_EXIT,       parserstate::stateExit)
END_STATE_MAP()



parserstate::parserstate()
{
}

parserstate::parserstate(istream* stream) : parser(stream)
{
}

parserstate::~parserstate()
{
}

bool parserstate::isComment()
{
  return false;
}

bool parserstate::eos(char &c)
{
  UNUSED_ARGUMENT(c);
  return false;
}

READ_FILE_RESULT parserstate::readRawData(string& data)
{
  READ_FILE_RESULT result = FILE_RESULT_OK;
  char             c      = '\0';
  data.clear();

  while(true)
  {
    c = pstream->get();
    if(pstream->eof() == true)
    {
      result = FILE_RESULT_EOF;
      return result;
    }

    if(pstream->bad() == true)
    {
      result = FILE_RESULT_BAD_SET;
      return result;
    }

    if(pstream->fail() == true)
    {
      result = FILE_RESULT_FAIL_SET;
      return result;
    }

    if(c == '\n' || c == '\r')
    {
      c = pstream->peek();
      if(c == '\n' || c == '\r')
        c = pstream->get();
      break;
    }
    else
     data.push_back(c);
  }
  return result;
}


READ_FILE_RESULT parserstate::readRawData()
{
  string           raw_data;
  READ_FILE_RESULT read_file_result = readRawData(raw_data);

  if(read_file_result == FILE_RESULT_OK)
    setRawData(raw_data);

  return read_file_result;
}

bool parserstate::readRawDataString()
{
  READ_FILE_RESULT result = readRawData();
  if(result == FILE_RESULT_OK || result == FILE_RESULT_SIZE_ZERO)
    return true;
  else
    return false;
}
const string& parserstate::getRawData()
{
  return rawdata;
}

void parserstate::setRawData(string & data)
{
  rawdata = data;
}

void parserstate::clearRawData()
{
  rawdata.clear();
}

void parserstate::start()
{
  string           raw_data;
  bool             is_read_next_string = true;
  READ_FILE_RESULT read_file_result    = FILE_RESULT_OK;

  setNextState(START_STATE);

  while(1)
  {
    if(is_read_next_string == true)
    {
      if(pstream->eof() == true)
      {
        setNextState(STATE_EXIT);
        is_read_next_string = false;
        continue;
      }

      read_file_result = readRawData(raw_data);
      setRawData(raw_data);

      if(read_file_result == FILE_RESULT_EOF)
      {
        setNextState(STATE_EXIT);
        is_read_next_string = false;
        continue;
      }
      else if(read_file_result == FILE_RESULT_SIZE_ZERO)
      {
       is_read_next_string = true;
       continue;
      }
    }

    if(isComment() != true)
    {
      pFunctionPntr fptr = statehandler(getNextState());
      is_read_next_string = (this->*fptr)();

      if(getNextState() == STATE_EXIT)
       break;
    }
    else /* skip comments */
    {
      is_read_next_string = true;
    }
  } /* while() end */
}

bool parserstate::stateStart(void)
{
  return true;
}

bool parserstate::stateExit(void)
{
  return false;
}
